#include "PolicyNode.h"

//////////////////////////////////////////////////////////////////////////
//Author	:	Ross Conroy ross.conroy@tees.ac.uk
//Date		:	14/08/2014
//
//Represents a node in a policy tree
//////////////////////////////////////////////////////////////////////////

PolicyNode::PolicyNode(void)
{
	_parent = NULL;
	_name = "NULL";
}

PolicyNode::PolicyNode(string name, list<string> observations, PolicyNode * parent)
{
	_name = name;
	_observations = observations;
	_parent = parent;
}

//A leaf node will not have any children assigned to it yet
bool PolicyNode::IsLeafNode()
{
	if(_children.size() == 0)
	{
		return true;
	}
	else
	{
		return false;
	}
}

//the final nodes will not have been assigned any observations
bool PolicyNode::IsFinalNode()
{
	if(_observations.size() == 0)
	{
		return true;
	}
	else
	{
		return false;
	}
}

//A root node would have no parent nodes
bool PolicyNode::IsRootNode()
{
	if(_parent == NULL)
	{
		return true;
	}
	else
	{
		return false;
	}
}

//root node time step = 1
//else time step = parent time step + 1
int PolicyNode::GetTimeStep()
{
	if(IsRootNode())
	{
		return 1;
	}
	else
	{
		return (_parent->GetTimeStep() + 1);
	}
}

//get combinations from parent node then appends name of observation
//that leads to the node passed in as self
list<string> PolicyNode::GetParentsCombinations(PolicyNode* self)
{
	list<string> parentHistory;

	if(!IsRootNode())
	{
		parentHistory = _parent->GetParentsCombinations(this);
	}

	parentHistory.push_back(_name);

	if(self != NULL)
	{
		for(hash_map<string, PolicyNode*>::const_iterator it = _children.begin(); it != _children.end(); it++)
		{
			PolicyNode * pn = it->second;
			if(pn == self)
			{
				parentHistory.push_back(it->first);
			}
		}
	}		

	return parentHistory;
}

//assigns a node no an observation
void PolicyNode::SetNodeForObservation(string observation, PolicyNode * node)
{
	_children.insert(make_pair(observation, node));
}

//follows a history to get the outcome action
string PolicyNode::GetActionForHistory(list<string> input)
{
	if(input.size() > 0)
	{
		if(input.front() == _name)
		{
			input.pop_front();
			string obs = input.front();
			input.pop_front();
			return _children[obs]->GetActionForHistory(input);
		}
		else			
		{
			return "";
		}
	}
	else
	{
		return _name;
	}
}
